package com.shenmazong.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.shenmazong.dto.TbJob;
import com.shenmazong.config.MqConfig;
import com.shenmazong.service.TbJobService;
import com.shenmazong.mapper.TbJobMapper;
import com.shenmazong.utils.ResultResponse;
import com.shenmazong.vo.BatchChooseIdVo;
import com.shenmazong.vo.ListParamVo;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.redisson.Redisson;
import org.redisson.api.LocalCachedMapOptions;
import org.redisson.api.RLocalCachedMap;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 *
 */
@Service
public class TbJobServiceImpl extends ServiceImpl<TbJobMapper, TbJob>
implements TbJobService{
    @Autowired
    private TbJobMapper tbJobMapper;
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Autowired
    private Redisson redisson;
    @Autowired
    private AmqpTemplate amqpTemplate;

    private ObjectMapper objectMapper=new ObjectMapper();
//    @Override
//    public ResultResponse findAllAdmin(ListParamVo listParamVo) {
//        Page<TbJob> page=tbJobMapper.findAllAdmin(new Page<TbJob>(listParamVo.getCurrent(),listParamVo.getSize()),listParamVo.getParamMap());
//        return ResultResponse.SUCCESS(page);
//    }

    @Override
    public ResultResponse findAllStudent(ListParamVo listParamVo) {
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<b style='color:red;'>").postTags("</b>").field("jobName");
        boolQuery.must(QueryBuilders.rangeQuery("deleteFlag").lte(0));
        if (!StringUtils.isEmpty(listParamVo.getParamMap().get("jobName"))){
            boolQuery.must(QueryBuilders.multiMatchQuery(listParamVo.getParamMap().get("jobName"),"jobName"));
        }
        if (!StringUtils.isEmpty(listParamVo.getParamMap().get("startTime"))){
            boolQuery.must(QueryBuilders.rangeQuery("createTime").gte(listParamVo.getParamMap().get("startTime")));
        }
        if (!StringUtils.isEmpty(listParamVo.getParamMap().get("endTime"))){
            boolQuery.must(QueryBuilders.rangeQuery("createTime").lte(listParamVo.getParamMap().get("endTime")));
        }
        NativeSearchQuery build = builder.withPageable(PageRequest.of(listParamVo.getCurrent()-1, listParamVo.getSize())).withQuery(boolQuery)
                .withHighlightBuilder(highlightBuilder).build();
        SearchHits<TbJob> hits = elasticsearchRestTemplate.search(build, TbJob.class);
        Page<TbJob> page = new Page<>();
        ArrayList<TbJob> list = new ArrayList<>();
        for (SearchHit<TbJob> hit : hits) {
            TbJob job = hit.getContent();
            if (hit.getHighlightField("jobName").size()>0){
                job.setJobName(hit.getHighlightField("jobName").get(0));
            }
            list.add(job);
        }
        page.setCurrent(listParamVo.getCurrent());
        page.setSize(listParamVo.getSize());
        page.setTotal(hits.getTotalHits());
        page.setRecords(list);
        return ResultResponse.SUCCESS(page);
    }

    @Override
    public ResultResponse saveJob(TbJob tbJob) {
        try {
            tbJobMapper.insert(tbJob);
            HashMap<String, String> map = new HashMap<>();
            map.put("saveJob",objectMapper.writeValueAsString(tbJob));
            amqpTemplate.convertAndSend(MqConfig.BOTIAN_EXCHANGE,MqConfig.JOB_KEY,objectMapper.writeValueAsString(map));
        } catch (Exception e) {
            e.printStackTrace();
            return ResultResponse.FAILED();
        }
        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse updateJob(TbJob tbJob) {
        try {
            TbJob job = tbJobMapper.selectById(tbJob.getJobId());
            if (!StringUtils.isEmpty(tbJob.getJobName())){
                job.setJobName(tbJob.getJobName());
            }
            job.setJobAudit((byte) 0);
            tbJobMapper.updateById(job);
            HashMap<String, String> map = new HashMap<>();
            map.put("saveJob",objectMapper.writeValueAsString(job));
            amqpTemplate.convertAndSend(MqConfig.BOTIAN_EXCHANGE,MqConfig.JOB_KEY,objectMapper.writeValueAsString(map));
        } catch (Exception e) {
            e.printStackTrace();
            return ResultResponse.FAILED();
        }
        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse deleteJob(BatchChooseIdVo batchChooseIdVo) {
        if (batchChooseIdVo.getIds().size()<=0){
            return ResultResponse.FAILED("至少选择一个哟");
        }
        try {
            HashMap<String, String> map = new HashMap<>();
            for (Long id : batchChooseIdVo.getIds()) {
               tbJobMapper.deleteById(id);
               map.put("delJob",objectMapper.writeValueAsString(id));
               amqpTemplate.convertAndSend(MqConfig.BOTIAN_EXCHANGE,MqConfig.JOB_KEY,objectMapper.writeValueAsString(map));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultResponse.FAILED();
        }
        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse cacheJob() {
        RLocalCachedMap<String, String> map = redisson.getLocalCachedMap("job", LocalCachedMapOptions.defaults());
        String job = map.get("job");
        List<TbJob> list =null;
        if (!StringUtils.isEmpty(job)){
            try {
                list = objectMapper.readValue(job, List.class);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return ResultResponse.SUCCESS(list);
        }
        list = tbJobMapper.selectList(new QueryWrapper<TbJob>().lambda().eq(TbJob::getDeleteFlag, 0));
        try {
            map.put("job",objectMapper.writeValueAsString(list));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return ResultResponse.SUCCESS(list);
    }

}




